﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Workflow.Runtime;
using System.Threading;
using CommonWFLibrary;
using System.Xml.Serialization;
using IndicoInterface;
using System.IO;
using IndicoInterface.SimpleAgendaDataModel;

namespace DeepTalkWFTest
{
    class Utilities
    {
        /// <summary>
        /// Run a test, throw exceptions back to user.
        /// </summary>
        /// <param name="wfActivity"></param>
        /// <param name="dict"></param>
        public static Dictionary<string,object> RunWFByType(Type wfActivity, Dictionary<string, object> dict)
        {
            using (WorkflowRuntime runtime = new WorkflowRuntime())
            using (AutoResetEvent reset = new AutoResetEvent(false))
            {
                Exception exp = null;
                Dictionary<string, object> r = null;
                runtime.WorkflowCompleted += (o, args) => { r = args.OutputParameters; reset.Set(); };
                runtime.WorkflowTerminated += (o, args) => { exp = args.Exception; reset.Set(); };

                LongRunningActivityBase.RegisterService(runtime);
                runtime.StartRuntime();

                WorkflowInstance instance;
                instance = runtime.CreateWorkflow(wfActivity, dict);
                instance.Start();
                reset.WaitOne();

                if (exp != null)
                {
                    throw exp;
                }

                return r;
            }
        }

        /// <summary>
        /// Run the WF, and turn on persitancy (though don't test any crashing).
        /// </summary>
        /// <param name="wfActivity"></param>
        /// <param name="dict"></param>
        /// <returns></returns>
        public static Dictionary<string, object> RunWFByTypeWPers(Type wfActivity, Dictionary<string, object> dict, DirectoryInfo cache)
        {
            using (WorkflowRuntime runtime = new WorkflowRuntime())
            using (AutoResetEvent reset = new AutoResetEvent(false))
            {
                Exception exp = null;
                Dictionary<string, object> r = null;
                runtime.WorkflowCompleted += (o, args) => { r = args.OutputParameters; reset.Set(); };
                runtime.WorkflowTerminated += (o, args) => { exp = args.Exception; reset.Set(); };

                runtime.AddService(new FilePersistenceService(true, cache));
                LongRunningActivityBinaryPersister lrp = new LongRunningActivityBinaryPersister(new FileInfo(cache.FullName + "\\longrunning"));
                LongRunningActivityBase.RegisterService(runtime, obj => lrp.Save(obj), () => lrp.Restore());

                runtime.StartRuntime();

                WorkflowInstance instance;
                instance = runtime.CreateWorkflow(wfActivity, dict);
                instance.Start();
                reset.WaitOne();

                if (exp != null)
                {
                    throw exp;
                }

                return r;
            }
        }

        static XmlSerializer _ser = new XmlSerializer(typeof(AgendaInfo));

        /// <summary>
        /// Return the Agenda turned into XML
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        internal static string AgendaAsXML(AgendaInfo info)
        {
            using (StringWriter wr = new StringWriter())
            {
                _ser.Serialize(wr, info);
                return wr.GetStringBuilder().ToString();
            }
        }

        /// <summary>
        /// Given a local file, build a talk around it.
        /// </summary>
        /// <param name="localfile"></param>
        /// <returns></returns>
        public static Talk TalkFromLocalFile(string localfile)
        {
            return TalkFromLocalFile(localfile, "");
        }

        /// <summary>
        /// Generate a talk from a single file, but rename it slightly by prepending.
        /// </summary>
        /// <param name="p"></param>
        /// <param name="p_2"></param>
        /// <returns></returns>
        public static Talk TalkFromLocalFile(string localfile, string prefix)
        {
            Talk t = new Talk() { ID = "5", StartDate = DateTime.Now, EndDate = DateTime.Now, Title = "Dude!" };
            FileInfo ftest = new FileInfo(localfile);
            FileInfo f = new FileInfo(prefix + ftest.Name);
            ftest.CopyTo(f.FullName);

            t.SlideURL = f.FullName;
            return t;
        }

        /// <summary>
        /// Given a single talk, build a meeting around it.
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public static Meeting MeetingFromTalks(Talk[] t)
        {
            Session s = new Session() { StartDate = DateTime.Now, ID = "5", EndDate = DateTime.Now, Title = "Bogus" };
            s.Talks = t;

            Meeting m = new Meeting() { Title = "no way", Sessions = new Session[] { s }, ID = "5", StartDate = DateTime.Now, EndDate = DateTime.Now };
            return m;
        }

        /// <summary>
        /// Create a meeting from a single talk.
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public static Meeting MeetingFromSingleTalk(Talk t)
        {
            return MeetingFromTalks(new Talk[] { t });
        }
    }
}
